package edu.chl.grupp11.aegas.controller.imp;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import org.farng.mp3.MP3File;
import org.farng.mp3.TagException;
import org.farng.mp3.id3.AbstractID3v2;
import org.farng.mp3.id3.ID3v1;

import edu.chl.grupp11.aegas.controller.AbstractTagHandler;
import edu.chl.grupp11.aegas.controller.ErrorControllerFactory;
import edu.chl.grupp11.aegas.controller.IErrorController;
import edu.chl.grupp11.aegas.model.AbstractConfig;
import edu.chl.grupp11.aegas.model.AbstractMetaTag;
import edu.chl.grupp11.aegas.model.ConfigFactory;
import edu.chl.grupp11.aegas.model.imp.ImmutableMetaTag;
import edu.chl.grupp11.aegas.model.imp.MutableMetaTag;
import edu.chl.grupp11.aegas.view.DropdownTagView;
import edu.chl.grupp11.aegas.view.TagView;

public class MP3Handler implements AbstractTagHandler {
	private static final long serialVersionUID = 4743532676450441081L;
	private AbstractConfig config = ConfigFactory.getSharedConfig();
	private IErrorController errorController = ErrorControllerFactory
			.getErrorController();

	@Override
	public boolean accepts(File f) {
		try {
			extractTags(f);
			return true;
		} catch (UnsupportedOperationException e) {
			return false;
		} catch (IOException e) {
			return false;
		} catch (TagException e) {
			return false;
		}
	}

	@Override
	public void editTag(File file, AbstractMetaTag tag, String newValue) {
		MP3File mp3 = null;
		boolean fail = false;
		try {
			mp3 = new MP3File(file);
			if (mp3.hasID3v2Tag()) {
				AbstractID3v2 id3v2Tag = mp3.getID3v2Tag();
				setID3v2Tag(id3v2Tag, tag, newValue);
			} else if (mp3.hasID3v1Tag()) {
				ID3v1 id3v1Tag = mp3.getID3v1Tag();
				setID3v1Tag(id3v1Tag, tag, newValue);
			}
			mp3.save();
		} catch (IOException e) {
			fail = true;
		} catch (TagException e) {
			fail = true;
		}

		if (fail) {
			errorController.setErrorMessage(null, config.getResourceBundle()
					.getString("error6"));
		}
	}

	@Override
	public ArrayList<AbstractMetaTag> extractTags(File file)
			throws UnsupportedOperationException, IOException, TagException {
		ArrayList<AbstractMetaTag> tags = new ArrayList<AbstractMetaTag>();
		MP3File mp3 = new MP3File(file);
		if (mp3.hasID3v2Tag()) {
			tags.add(new MutableMetaTag("Lead Artist", mp3.getID3v2Tag()
					.getLeadArtist()));
			tags.add(new MutableMetaTag("Title", mp3.getID3v2Tag()
					.getSongTitle()));
			tags.add(new MutableMetaTag("Album", mp3.getID3v2Tag()
					.getAlbumTitle()));
			tags.add(new MutableMetaTag("Author Composer", mp3.getID3v2Tag()
					.getAuthorComposer()));
			tags.add(new ImmutableMetaTag("Identifier", mp3.getID3v2Tag()
					.getIdentifier()));
			tags.add(new MutableMetaTag("Song Comment", mp3.getID3v2Tag()
					.getSongComment()));
			tags.add(new MutableMetaTag("Song Genre", mp3.getID3v2Tag()
					.getSongGenre()));
			tags.add(new MutableMetaTag("Song Lyric", mp3.getID3v2Tag()
					.getSongLyric()));
			tags.add(new MutableMetaTag("Track Number On Album", mp3
					.getID3v2Tag().getTrackNumberOnAlbum()));
			tags.add(new MutableMetaTag("Year Released", mp3.getID3v2Tag()
					.getYearReleased()));
		} else if (mp3.hasID3v1Tag()) {
			tags.add(new MutableMetaTag("Lead Artist", mp3.getID3v1Tag()
					.getArtist()));
			tags.add(new MutableMetaTag("Title", mp3.getID3v1Tag().getTitle()));
			tags.add(new MutableMetaTag("Album", mp3.getID3v1Tag().getAlbum()));
			tags.add(new ImmutableMetaTag("Identifier", mp3.getID3v1Tag()
					.getIdentifier()));
			tags.add(new MutableMetaTag("Song Genre", mp3.getID3v1Tag()
					.getSongGenre()));
			tags.add(new MutableMetaTag("Track Number On Album", mp3
					.getID3v1Tag().getTrackNumberOnAlbum()));
			tags.add(new MutableMetaTag("Year Released", mp3.getID3v1Tag()
					.getYearReleased()));
		} else {
			throw new UnsupportedOperationException();
		}

		return tags;
	}

	@Override
	public ArrayList<TagView> getTagViews(File file) {
		ArrayList<TagView> tagViews = new ArrayList<TagView>();
		boolean fail = false;

		try {
			MP3File mp3 = new MP3File(file);
			for (AbstractMetaTag tag : extractTags(file)) {
				if (tag.getName().equals("Song Genre") && !mp3.hasID3v2Tag()) {
					tagViews.add(new DropdownTagView(tag));
				} else {
					tagViews.add(new TagView(tag));
				}
			}
		} catch (UnsupportedOperationException e) {
			fail = true;
		} catch (IOException e) {
			fail = true;
		} catch (TagException e) {
			fail = true;
		}

		if (fail) {
			errorController.setErrorMessage(null, config.getResourceBundle()
					.getString("error6"));
		}
		return tagViews;
	}

	private void setID3v1Tag(ID3v1 id3Tag, AbstractMetaTag tag, String newValue) {
		String tagName = tag.getName();
		if (tagName == "Album") {
			id3Tag.setAlbumTitle(newValue);
		} else if (tagName == "Album Title") {
			id3Tag.setAlbumTitle(newValue);
		} else if (tagName == "Author Composer") {
			id3Tag.setAuthorComposer(newValue);
		} else if (tagName == "Comment") {
			id3Tag.setSongComment(newValue);
		} else if (tagName == "Song Genre") {
			id3Tag.setSongGenre(newValue);
		} else if (tagName == "Song Comment") {
			id3Tag.setSongComment(newValue);
		} else if (tagName == "Song Lyric") {
			id3Tag.setSongLyric(newValue);
		} else if (tagName == "Song Title") {
			id3Tag.setSongTitle(newValue);
		} else if (tagName == "Title") {
			id3Tag.setSongTitle(newValue);
		} else if (tagName == "Track Number On Album") {
			id3Tag.setTrackNumberOnAlbum(newValue);
		} else if (tagName == "Lead Artist") {
			id3Tag.setArtist(newValue);
		} else if (tagName == "Year Released") {
			id3Tag.setYearReleased(newValue);
		}
	}

	private void setID3v2Tag(AbstractID3v2 id3Tag, AbstractMetaTag tag,
			String newValue) {
		String tagName = tag.getName();
		if (tagName == "Album") {
			id3Tag.setAlbumTitle(newValue);
		} else if (tagName == "Album Title") {
			id3Tag.setAlbumTitle(newValue);
		} else if (tagName == "Author Composer") {
			id3Tag.setAuthorComposer(newValue);
		} else if (tagName == "Comment") {
			id3Tag.setSongComment(newValue);
		} else if (tagName == "Song Genre") {
			id3Tag.setSongGenre(newValue);
		} else if (tagName == "Song Comment") {
			id3Tag.setSongComment(newValue);
		} else if (tagName == "Song Lyric") {
			id3Tag.setSongLyric(newValue);
		} else if (tagName == "Song Title") {
			id3Tag.setSongTitle(newValue);
		} else if (tagName == "Title") {
			id3Tag.setSongTitle(newValue);
		} else if (tagName == "Track Number On Album") {
			id3Tag.setTrackNumberOnAlbum(newValue);
		} else if (tagName == "Lead Artist") {
			id3Tag.setLeadArtist(newValue);
		} else if (tagName == "Year Released") {
			id3Tag.setYearReleased(newValue);
		}
	}

}
